// axios.js
import type { InternalAxiosRequestConfig } from "axios"
import axios from "axios"
import { AUTHENTICATION_FAILED_ERROR } from "@/api/error-code"
import router from "@/router"
import { ACCESS_TOKEN_NAME } from "@/utils/constants"
import { useLocalStorage } from "@vueuse/core"
import { useEnvMode } from "@/utils/env-util"
import { APPLICATION_JSON } from "@/api/content-type"

const accessToken = useLocalStorage(ACCESS_TOKEN_NAME, "")

//baseUrl当开发模式根据环境变量设置，当生产模型就直接使用服务地址
axios.defaults.baseURL = useEnvMode(import.meta.env.VITE_REQUEST_BASE_URL, window.location.origin)
// 默认 post 请求，使用 application/json 形式
// axios.defaults.headers.post["Content-Type"] = "application/json;charset=UTF-8"

// 添加请求拦截器
axios.interceptors.request.use(
  function (config: InternalAxiosRequestConfig) {
    // 在发送请求之前做些什么
    if (accessToken.value) {
      config.headers[ACCESS_TOKEN_NAME] = accessToken.value
    }
    return config
  },
  function (error) {
    // 对请求错误做些什么
    console.log(error)
    return Promise.reject(error)
  }
)

// 请求拦截器，内部根据返回值，重新组装，统一管理。
axios.interceptors.response.use(
  (res) => {
    if (typeof res !== "object" || res.status < 200 || res.status >= 400) {
      window.$message.error("服务异常!")
      // console.log(res)
      return Promise.reject(res)
    }
    if (!res.data || res.data.code === AUTHENTICATION_FAILED_ERROR) {
      window.$message.error("认证错误或登陆过期，请重新登陆")
      router
        .push({
          path: "/"
        })
        .then(() => undefined)
      return Promise.reject(res)
    }

    if (!res.data || res.data.code !== 0) {
      window.$message.error(res.data.msg)
      // console.log(res)
      return Promise.reject(res)
    }
    return res
  },
  () => {
    window.$message.error("未知错误!")
  }
)

export default axios

export function get<T = unknown, R = T, D = unknown>(
  url: string,
  contentType: string = APPLICATION_JSON
): Promise<R> {
  return new Promise((resolve) =>
    axios
      .get(url, {
        headers: {
          "Content-Type": contentType
        }
      })
      .then(
        (response) => {
          resolve(response.data)
        },
        () => {}
      )
  )
}

export function post<T = never, R = T, D = unknown>(
  url: string,
  data?: D,
  contentType: string = APPLICATION_JSON
): Promise<R> {
  return new Promise((resolve) =>
    axios
      .post(url, data, {
        headers: {
          "Content-Type": contentType
        }
      })
      .then(
        (response) => {
          resolve(response.data)
        },
        () => {}
      )
  )
}
